package com.learner.search.service;

import com.learner.common.exception.ExceptionUtil;
import com.learner.common.exception.RestException;
import com.learner.common.http.QueryResult;
import com.learner.pojo.course.CoursePub;
import com.learner.pojo.search.EsCourseKeys;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description: 搜索的逻辑处理
 * @Author: ice2020x
 * @Date: 2021/8/22
 */
@Service
@Slf4j
public class EsCourseService {

    @Value("${learner.course.index}")
    private String index;
    @Value("${learner.course.type}")
    private String type;
    @Value("${learner.course.source_field}")
    private String sourceField;


    @Autowired
    RestHighLevelClient client;

    @Autowired
    RestClient restClient;

    /**
     * 通过关键字查询
     *
     * @param page         page
     * @param size         size
     * @param esCourseKeys es查询条件
     * @return 文件
     */
    public QueryResult<CoursePub> listByKeys(int page, int size, EsCourseKeys esCourseKeys) {
        // 先创建关键字对象
        if (esCourseKeys == null) {
            esCourseKeys = new EsCourseKeys();
        }
        QueryResult<CoursePub> coursePubQueryResult = new QueryResult<>();
        // 初始化
        SearchRequest searchRequest = new SearchRequest(index);
        searchRequest.types(type);
        String[] sourceFields = sourceField.split(",");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.fetchSource(sourceFields, new String[]{});

        // 创建一个布尔查询对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();


        if (StringUtils.isNoneEmpty(esCourseKeys.getKeyword())) {
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(
                            esCourseKeys.getKeyword(),
                            "name", "description", "courseplan")
                    .field("name", 10)
                    .minimumShouldMatch("70%");
            boolQueryBuilder.must(multiMatchQueryBuilder);
        }


        if (StringUtils.isNoneEmpty(esCourseKeys.getMt())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("mt", esCourseKeys.getMt()));

        }
        // 根据二级分类
        if (StringUtils.isNoneEmpty(esCourseKeys.getSt())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("st", esCourseKeys.getSt()));
        }

        // 根据难度等级
        if (StringUtils.isNoneEmpty(esCourseKeys.getGrade()) && Integer.parseInt(esCourseKeys.getGrade()) != 0) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("grade", esCourseKeys.getGrade()));
        }

        if (StringUtils.isNoneEmpty(esCourseKeys.getCharge())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("charge", esCourseKeys.getCharge()));
        }

        if (esCourseKeys.getPrice_max() != 0 && esCourseKeys.getPrice_max() != null && esCourseKeys.getPrice_min() != null) {
            System.out.println("--------------------进入");
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
            rangeQueryBuilder.gte(esCourseKeys.getPrice_min());
            rangeQueryBuilder.lte(esCourseKeys.getPrice_max());
            boolQueryBuilder.filter(rangeQueryBuilder);
        }

        if (StringUtils.isNotBlank(esCourseKeys.getSort())) {
            searchSourceBuilder.sort(esCourseKeys.getSort(), SortOrder.DESC);
        }
        searchSourceBuilder.query(boolQueryBuilder);
        if (page <= 0) {
            page = 1;
        }
        if (size <= 0) {
            size = 12;
        }
        //起始记录下标
        int from = (page - 1) * size;
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);

        searchRequest.source(searchSourceBuilder);

        List<CoursePub> list = new ArrayList<>();
        try {
            SearchResponse searchResponse = client.search(searchRequest);
            SearchHits hits = searchResponse.getHits();
            long totalHits = hits.getTotalHits();
            coursePubQueryResult.setTotal(totalHits);
            SearchHit[] hitss = hits.getHits();
            for (SearchHit documentFields : hitss) {
                CoursePub coursePub = bindCoursePub(documentFields);
                list.add(coursePub);
            }
        } catch (IOException e) {
            log.info("查询课程失败");
            throw ExceptionUtil.createException(RestException.class, 4500001);
        }
        coursePubQueryResult.setList(list);

        return coursePubQueryResult;
    }


    private CoursePub bindCoursePub(SearchHit documentFields) {
        CoursePub coursePub = new CoursePub();
        Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
        String courseId = (String) sourceAsMap.get("id");
        String name = (String) sourceAsMap.get("name");
        String grade = (String) sourceAsMap.get("grade");
        String charge = (String) sourceAsMap.get("charge");
        String pic = (String) sourceAsMap.get("pic");
        String description = (String) sourceAsMap.get("description");
        String coursePlan = (String) sourceAsMap.get("courseplan");
        String users = (String) sourceAsMap.get("users");
        String ap = (String) sourceAsMap.get("ap");
        String st = (String) sourceAsMap.get("st");
        String mt = (String) sourceAsMap.get("mt");
        String teacherName = (String) sourceAsMap.get("teacher_name");
        String userId = (String) sourceAsMap.get("userid");
        String vaild = (String) sourceAsMap.get("charge");
        Integer viewCount = (Integer) sourceAsMap.get("view_count");
        Integer buyCount = (Integer) sourceAsMap.get("buy_count");
        Double price = null;
        try {
            if (sourceAsMap.get("price") != null) {
                price = (Double) sourceAsMap.get("price");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        //旧价格
        Double price_old = null;
        try {
            if (sourceAsMap.get("price_old") != null && (Integer) sourceAsMap.get("price_old") != 0) {
                price_old = (Double) sourceAsMap.get("price_old");
            }
        } catch (Exception ignored) {
        }
        coursePub.setId(courseId);
        coursePub.setName(name);
        coursePub.setUsers(users);
        coursePub.setSt(st);
        coursePub.setMt(mt);
        coursePub.setCharge(charge);
        coursePub.setGrade(grade);
        coursePub.setDescription(description);
        coursePub.setValid(vaild);
        if (price != null) {
            coursePub.setPrice(BigDecimal.valueOf(price));
        }
        if (price_old != null) {
            coursePub.setPrice(BigDecimal.valueOf(price_old));
        }
        coursePub.setPic(pic);
        coursePub.setCoursePlan(coursePlan);
        coursePub.setAp(ap);
        coursePub.setTeacherName(teacherName);
        coursePub.setUserId(userId);
        if (buyCount != null) {
            coursePub.setBuyCount(Long.valueOf(buyCount));
        }
        if (viewCount != null) {
            coursePub.setViewCount(Long.valueOf(viewCount));
        }
        return coursePub;
    }
}
